#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/poll.h>

#define maxNum 10
#define NUM 10

// 线程的函数参数
struct tp_work_args_s {
    void* arg;
};

// 线程的工作函数
struct tp_work_s {
    void* (*process_job)(void* arg);
};

typedef struct tp_work_args_s tp_work_arg;
typedef struct tp_work_s tp_work;

struct tp_thread_info_s {
    pthread_t thread_id;      // 线程ID
    int status;              // 线程状态 1忙 0 闲
    int need_exit;           // 退出标记 1 退出 0 不用退出
    pthread_mutex_t thread_lock;
    pthread_cond_t thread_cond; // 条件变量

    tp_work* th_work;
    tp_work_arg* th_arg;
    struct tp_thread_pool_s* pool; // 添加线程池指针，用于访问空闲线程数
    struct tp_thread_info_s* next;
    struct tp_thread_info_s* prev;
};

// 线程池类
struct tp_thread_pool_s {
    int min_th_num;          // 线程池线程最小数量
    int cur_th_num;          // 当前线程数
    int max_th_num;          // 线程池中线程最大数量
    int idle_th_num;         // 当前空闲线程数
    pthread_mutex_t tp_lock; // 互斥
    pthread_t manage_thread_id; // 管理线程ID

    struct tp_thread_info_s* thread_info; // 线程列表头节点
};

typedef struct tp_thread_info_s tp_thread_info;
typedef struct tp_thread_pool_s tp_thread_pool;

// 函数声明
tp_thread_pool* create_thread_pool(int min, int max);
int tp_add_job(tp_thread_pool* pool, tp_work* worker, tp_work_arg* arg);
tp_thread_info* create_thread(int num);
int init_thread_pool(tp_thread_pool* pool);
void* tp_manager_thread(void* arg);
int init_thread(tp_thread_pool* pool, tp_thread_info* info);
tp_thread_info* tp_add_pthread(tp_thread_pool* pool);
void* thread_worker(void* arg);
void* myWork(void* arg);

// 工作线程函数
void* thread_worker(void* arg) {
    tp_thread_info* thread_info = (tp_thread_info*)arg;
    tp_thread_pool* pool = thread_info->pool;

    while (1) {
        pthread_mutex_lock(&(thread_info->thread_lock));

        // 等待任务分配或退出信号[6,8](@ref)
        while (thread_info->th_work == NULL && !thread_info->need_exit) {
            pthread_cond_wait(&(thread_info->thread_cond), &(thread_info->thread_lock));
        }

        // 检查是否需要退出[6](@ref)
        if (thread_info->need_exit) {
            pthread_mutex_unlock(&(thread_info->thread_lock));
            printf("线程%lu退出\n", (unsigned long)thread_info->thread_id);
            break;
        }

        // 执行任务
        tp_work* work = thread_info->th_work;
        tp_work_arg* work_arg = thread_info->th_arg;

        // 重置工作指针，表示线程准备接受新任务
        thread_info->th_work = NULL;
        thread_info->th_arg = NULL;

        pthread_mutex_unlock(&(thread_info->thread_lock));

        // 实际执行工作[4](@ref)
        if (work && work->process_job) {
            work->process_job(work_arg->arg);
        }

        // 任务完成，更新状态
        pthread_mutex_lock(&(thread_info->thread_lock));
        thread_info->status = 0; // 设置为空闲

        // 更新线程池的空闲线程数[8](@ref)
        pthread_mutex_lock(&(pool->tp_lock));
        pool->idle_th_num++;
        pthread_mutex_unlock(&(pool->tp_lock));

        pthread_mutex_unlock(&(thread_info->thread_lock));

        // 释放任务参数内存
        if (work_arg) {
            free(work_arg);
        }
    }

    return NULL;
}

// 创建线程池
tp_thread_pool* create_thread_pool(int min, int max) {
    tp_thread_pool* pool = (tp_thread_pool*)malloc(sizeof(tp_thread_pool));
    if (NULL == pool) {
        printf("create_thread_pool 函数中开内存失败：%m\n");
        return NULL;
    }

    // 初始化成员[8](@ref)
    memset(pool, 0, sizeof(tp_thread_pool));

    if (min < 3) min = 3;
    if (max > 200) max = 200;

    pool->min_th_num = min;
    pool->max_th_num = max;
    pool->cur_th_num = min;
    pool->idle_th_num = min;

    pthread_mutex_init(&(pool->tp_lock), NULL);

    // 创建线程信息链表
    pool->thread_info = create_thread(pool->cur_th_num);
    if (NULL == pool->thread_info) {
        free(pool);
        return NULL;
    }

    if (!init_thread_pool(pool)) {
        // 初始化失败，清理资源
        printf("初始化线程池失败\n");
        // 需要添加清理代码
        free(pool);
        return NULL;
    }

    return pool;
}

// 创建线程池中的线程
tp_thread_info* create_thread(int num) {
    if (num < 1) return NULL;

    tp_thread_info* head = NULL;
    tp_thread_info* cur = NULL;
    tp_thread_info* prev = NULL;

    // 创建所有线程节点[4](@ref)
    for (int i = 0; i < num; i++) {
        cur = (tp_thread_info*)malloc(sizeof(tp_thread_info));
        if (NULL == cur) {
            printf("create_thread函数中申请内存失败:%m\n");
            // 需要清理已分配的内存
            while (head != NULL) {
                cur = head;
                head = head->next;
                free(cur);
            }
            return NULL;
        }

        memset(cur, 0, sizeof(tp_thread_info));

        if (head == NULL) {
            head = cur;
        } else {
            prev->next = cur;
            cur->prev = prev;
        }
        prev = cur;
    }

    return head;
}

// 初始化线程池
int init_thread_pool(tp_thread_pool* pool) {
    tp_thread_info* thread_info;

    // 创建并初始化线程对象[8](@ref)
    for (thread_info = pool->thread_info; thread_info != NULL; thread_info = thread_info->next) {
        thread_info->pool = pool; // 设置线程池指针
        if (init_thread(pool, thread_info)) {
            printf("初始化线程ID：%lu成功\n", (unsigned long)thread_info->thread_id);
        } else {
            printf("初始化线程失败\n");
            return 0;
        }
    }

    // 创建管理线程[4](@ref)
    int ret = pthread_create(&(pool->manage_thread_id), NULL, tp_manager_thread, pool);
    if (ret != 0) {
        printf("创建管理线程失败:%m\n");
        return 0;
    } else {
        printf("创建管理线程成功，管理线程ID：%lu\n", (unsigned long)pool->manage_thread_id);
    }
    return 1;
}

// 初始化线程
int init_thread(tp_thread_pool* pool, tp_thread_info* info) {
    // 初始化锁和条件变量[6](@ref)
    pthread_mutex_init(&(info->thread_lock), NULL);
    pthread_cond_init(&(info->thread_cond), NULL);

    info->status = 0; // 初始状态为空闲
    info->need_exit = 0;
    info->th_work = NULL;
    info->th_arg = NULL;
    info->pool = pool;

    int r = pthread_create(&(info->thread_id), NULL, thread_worker, info);
    if (r != 0) {
        printf("init_thread函数中创建并启动线程失败：%m\n");
        return 0;
    }

    return 1;
}

// 向线程池中添加任务
int tp_add_job(tp_thread_pool* pool, tp_work* worker, tp_work_arg* arg) {
    tp_thread_info* info;

    pthread_mutex_lock(&(pool->tp_lock));

    // 先去线程池找空闲线程[8](@ref)
    for (info = pool->thread_info; info != NULL; info = info->next) {
        pthread_mutex_lock(&(info->thread_lock));
        if (info->status == 0 && info->need_exit == 0) { // 空闲且不需要退出
            printf("线程%lu空闲\n", (unsigned long)info->thread_id);

            // 设置为忙碌
            info->status = 1;
            pool->idle_th_num--;

            info->th_work = worker;
            info->th_arg = arg;

            pthread_mutex_unlock(&(pool->tp_lock));
            pthread_cond_signal(&(info->thread_cond));
            pthread_mutex_unlock(&(info->thread_lock));
            return 1;
        }
        pthread_mutex_unlock(&(info->thread_lock));
    }

    // 没有空闲线程，尝试新增线程[4](@ref)
    if (pool->cur_th_num < pool->max_th_num) {
        tp_thread_info* newInfo = tp_add_pthread(pool);
        if (newInfo) {
            pthread_mutex_lock(&(newInfo->thread_lock));
            newInfo->status = 1; // 新线程立即工作
            pool->idle_th_num--; // 空闲数减少

            newInfo->th_work = worker;
            newInfo->th_arg = arg;

            pthread_mutex_unlock(&(pool->tp_lock));
            pthread_cond_signal(&(newInfo->thread_cond));
            pthread_mutex_unlock(&(newInfo->thread_lock));
            return 1;
        }
    }

    pthread_mutex_unlock(&(pool->tp_lock));

    // 线程池已满，无法添加任务
    printf("线程池已满，无法添加任务\n");
    return 0;
}

// 通知管理线程增加一个线程
tp_thread_info* tp_add_pthread(tp_thread_pool* pool) {
    if (pool->cur_th_num >= pool->max_th_num) {
        return NULL;
    }

    // 添加一个线程节点到pool->thread_info末尾[4](@ref)
    tp_thread_info* tail = pool->thread_info;
    while (tail->next != NULL) {
        tail = tail->next;
    }

    tp_thread_info* newInfo = (tp_thread_info*)malloc(sizeof(tp_thread_info));
    if (NULL == newInfo) {
        return NULL;
    }

    memset(newInfo, 0, sizeof(tp_thread_info));
    newInfo->next = NULL;
    newInfo->prev = tail;
    newInfo->pool = pool;
    tail->next = newInfo;

    // 初始化线程
    if (!init_thread(pool, newInfo)) {
        free(newInfo);
        tail->next = NULL;
        return NULL;
    }

    pool->cur_th_num++;
    pool->idle_th_num++; // 新线程初始为空闲

    printf("tp_add_pthread 增加一个新线程成功:%lu\n", (unsigned long)newInfo->thread_id);
    return newInfo;
}

// 管理线程的函数[4](@ref)
void* tp_manager_thread(void* arg) {
    tp_thread_pool* thisPool = (tp_thread_pool*)arg;
    int idle_arg[3] = {0};
    int averIdle = 0;

    while (1) {
        pthread_mutex_lock(&(thisPool->tp_lock));

        int cur = thisPool->cur_th_num;
        int idle = thisPool->idle_th_num;
        int min = thisPool->min_th_num;
        int exit_num = 0;

        idle_arg[2] = idle;
        averIdle = (idle_arg[0] + idle_arg[1] + idle_arg[2]) / 3;

        printf("************************服务器当前状态**********************\n");
        printf("总线程数：%d\n", cur);
        printf("当前空闲线程数：%d\n", idle);
        printf("平均空闲线程数：%d\n", averIdle);

        if (averIdle > (cur / 2) && cur > min) {
            // 空闲线程过多，需要销毁一些[4](@ref)
            exit_num = cur / 5;
            if (exit_num < 1) exit_num = 1;

            // 修正，确保不会销毁到最小线程数以下
            if (cur - exit_num < min) {
                exit_num = cur - min;
            }
        }

        printf("需要销毁%d个线程\n", exit_num);

        // 标记需要退出的线程[6](@ref)
        tp_thread_info* info;
        for (info = thisPool->thread_info; info != NULL && exit_num > 0; info = info->next) {
            pthread_mutex_lock(&(info->thread_lock));
            if (info->status == 0 && info->need_exit == 0) { // 空闲线程
                info->need_exit = 1; // 标记为退出线程
                exit_num--;
                pthread_cond_signal(&(info->thread_cond)); // 唤醒线程使其退出
            }
            pthread_mutex_unlock(&(info->thread_lock));
        }

        pthread_mutex_unlock(&(thisPool->tp_lock));

        idle_arg[0] = idle_arg[1];
        idle_arg[1] = idle_arg[2];

        // 每隔5s统计1次[4](@ref)
        sleep(5);
    }

    return NULL;
}

// 工作函数
void* myWork(void* arg) {
    int val = *((int*)arg);
    printf("工作函数：%d开始\n", val);
    sleep(2); // 缩短睡眠时间以便测试
    printf("工作函数：%d结束\n", val);
    return NULL;
}

int main() {
    int num = NUM;
    int* working = (int*)malloc(sizeof(int) * NUM); // 改为动态分配

    // 1.创建线程池[8](@ref)
    tp_thread_pool* pool = create_thread_pool(3, 20);
    if (pool == NULL) {
        printf("创建线程池失败\n");
        free(working);
        return -1;
    }

    // 任务池
    tp_work* worker = (tp_work*)malloc(sizeof(tp_work));
    worker->process_job = myWork;

    for (int i = 0; i < num; i++) {
        tp_work_arg* arg = (tp_work_arg*)malloc(sizeof(tp_work_arg));
        working[i] = i + 60;
        arg->arg = (void*)&(working[i]);
        tp_add_job(pool, worker, arg);
    }

    sleep(10); // 等待任务执行完成

    // 清理资源
    free(working);
    free(worker);

    // 注意：实际项目中需要添加线程池销毁逻辑
    printf("程序执行完毕\n");
    return 0;
}